###############################################################################
# SuperLinks                                                                  #
# Copyright (c) 2000-2007 Greg Nolle (http://greg.nolle.co.uk)                #
###############################################################################
# This program is free software; you can redistribute it and/or modify it     #
# under the terms of the GNU General Public License as published by the Free  #
# Software Foundation; either version 2 of the License, or (at your option)   #
# any later version.                                                          #
#                                                                             #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   #
# more details.                                                               ##                                                                             #
# You should have received a copy of the GNU General Public License along     #
# with this program; if not, write to the Free Software Foundation, Inc.,     #
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                 #
###############################################################################
# Action.pm.pl -> Action module                                               #
###############################################################################
# DON'T EDIT BELOW UNLESS YOU KNOW WHAT YOU'RE DOING!                         #
###############################################################################
package Action;

BEGIN { require "System.pm.pl"; import System qw($SYSTEM); }
BEGIN { require "General.pm.pl"; import General qw($GENERAL); }
require "Error.pm.pl";

use strict;

%SL::ACTIONS = (
  "SL"  => {
   # action                 => [module, subroutine]
    "Add"                   => ["Add", "show"],
    "DoAdd"                 => ["Add", "do"],
    "Search"                => ["Search", "show"],
    "DoSearch"              => ["Search", "do"],
    "Category"              => ["Category", "show"],
    "Jump"                  => ["Jump", "show"],
    "Detail"                => ["Detail", "show"],
    "Modify"                => ["Modify", "show"],
    "ViewModify"            => ["Modify", "view"],
    "DoModify"              => ["Modify", "do"],
    "DoRate"                => ["Rate", "do"],
    "Review"                => ["Review", "show"],
    "DoReview"              => ["Review", "do"],
    "New"                   => ["New", "show"],
    "Hot"                   => ["Hot", "show"],
    "Cool"                  => ["Cool", "show"],
    "Page"                  => ["Page", "show"],
    "Index"                 => ["Index", "show"],
    "DeadLink"              => ["DeadLink", "show"],
    "DoDeadLink"            => ["DeadLink", "do"],
    "StyleSheet"            => ["StyleSheet", "show"],
    "Remove"                => ["Remove", "show"],
    "DoRemove"              => ["Remove", "do"],
    "RetrievePassword"      => ["RetrievePassword", "show"],
    "DoRetrievePassword"    => ["RetrievePassword", "do"],
    "Recommend"             => ["Recommend", "show"],
    "DoRecommend"           => ["Recommend", "do"],
    "Random"                => ["Random", "show"]
  },
  "CP"  => {
   # action                 => [module, subroutine]
    "Login"                 => ["Login", "show"],
    "DoLogin"               => ["Login", "do"],
    "Logout"                => ["Logout", "show"],
    "Menu"                  => ["Menu", "show"],
    "Index"                 => ["Index", "show"],
    "Summary"               => ["Summary", "show"],
    "ExtraFields"           => ["ExtraFields", "show"],
    "Categories"            => ["Categories", "show"],
    "Resources"             => ["Resources", "show"],
    "SearchResources"       => ["SearchResources", "show"],
    "DoSearchResources"     => ["SearchResources", "do"],
    "Reviews"               => ["Reviews", "show"],
    "Admins"                => ["Admins", "show"],
    "Levels"                => ["Levels", "show"],
    "Backups"               => ["Backups", "show"],
    "CreateBackup"          => ["CreateBackup", "show"],
    "DoCreateBackup"        => ["CreateBackup", "do"],
    "DoRemoveBackups"       => ["RemoveBackups", "do"],
    "ViewBackup"            => ["ViewBackup", "show"],
    "RestoreBackup"         => ["RestoreBackup", "show"],
    "DoRestoreBackup"       => ["RestoreBackup", "do"],
    "Expire"                => ["Expire", "show"],
    "DoExpire"              => ["Expire", "do"],
    "ImportExport"          => ["ImportExport", "show"],
    "DoImportExport"        => ["ImportExport", "do"],
    "Skins"                 => ["Skins", "show"],
    "StyleSheets"           => ["StyleSheets", "show"],
    "TemplateSets"          => ["TemplateSets", "show"],
    "LanguageSets"          => ["LanguageSets", "show"],
    "CreateTemplateSet"     => ["CreateTemplateSet", "show"],
    "DoCreateTemplateSet"   => ["CreateTemplateSet", "do"],
    "ModifyTemplateSet"     => ["ModifyTemplateSet", "show"],
    "DoModifyTemplateSet"   => ["ModifyTemplateSet", "do"],
    "DoRemoveTemplateSets"  => ["RemoveTemplateSets", "do"],
    "Templates"             => ["Templates", "show"],
    "ModifyTemplate"        => ["ModifyTemplate", "show"],
    "DoModifyTemplate"      => ["ModifyTemplate", "do"],
    "CreateLanguageSet"     => ["CreateLanguageSet", "show"],
    "DoCreateLanguageSet"   => ["CreateLanguageSet", "do"],
    "ModifyLanguageSet"     => ["ModifyLanguageSet", "show"],
    "DoModifyLanguageSet"   => ["ModifyLanguageSet", "do"],
    "DoRemoveLanguageSets"  => ["RemoveLanguageSets", "do"],
    "Languages"             => ["Languages", "show"],
    "ModifyLanguage"        => ["ModifyLanguage", "show"],
    "DoModifyLanguage"      => ["ModifyLanguage", "do"],
    "CreateSkin"            => ["CreateSkin", "show"],
    "DoCreateSkin"          => ["CreateSkin", "do"],
    "DoRemoveSkins"         => ["RemoveSkins", "do"],
    "ModifySkin"            => ["ModifySkin", "show"],
    "DoModifySkin"          => ["ModifySkin", "do"],
    "DoRemoveSkins"         => ["RemoveSkins", "do"],
    "ModifyStyleSheet"      => ["ModifyStyleSheet", "show"],
    "DoModifyStyleSheet"    => ["ModifyStyleSheet", "do"],
    "DoRemoveStyleSheets"   => ["RemoveStyleSheets", "do"],
    "CreateStyleSheet"      => ["CreateStyleSheet", "show"],
    "DoCreateStyleSheet"    => ["CreateStyleSheet", "do"],
    "DoRemoveStyleSheets"   => ["RemoveStyleSheets", "do"],
    "ApproveResources"      => ["ApproveResources", "show"],
    "DoApproveResources"    => ["ApproveResources", "do"],
    "SystemOptions"         => ["SystemOptions", "show"],
    "DoSystemOptions"       => ["SystemOptions", "do"],
    "GeneralOptions"        => ["GeneralOptions", "show"],
    "DoGeneralOptions"      => ["GeneralOptions", "do"],
    "CreateCategory"        => ["CreateCategory", "show"],
    "DoCreateCategory"      => ["CreateCategory", "do"],
    "ModifyCategory"        => ["ModifyCategory", "show"],
    "DoModifyCategory"      => ["ModifyCategory", "do"],
    "RemoveCategories"      => ["RemoveCategories", "show"],
    "DoRemoveCategories"    => ["RemoveCategories", "do"],
    "CreateResource"        => ["CreateResource", "show"],
    "DoCreateResource"      => ["CreateResource", "do"],
    "ModifyResource"        => ["ModifyResource", "show"],
    "DoModifyResource"      => ["ModifyResource", "do"],
    "DoRemoveResources"     => ["RemoveResources", "do"],
    "CreateAdmin"           => ["CreateAdmin", "show"],
    "DoCreateAdmin"         => ["CreateAdmin", "do"],
    "ModifyAdmin"           => ["ModifyAdmin", "show"],
    "DoModifyAdmin"         => ["ModifyAdmin", "do"],
    "DoRemoveAdmins"        => ["RemoveAdmins", "do"],
    "CreateLevel"           => ["CreateLevel", "show"],
    "DoCreateLevel"         => ["CreateLevel", "do"],
    "ModifyLevel"           => ["ModifyLevel", "show"],
    "DoModifyLevel"         => ["ModifyLevel", "do"],
    "RemoveLevels"          => ["RemoveLevels", "show"],
    "DoRemoveLevels"        => ["RemoveLevels", "do"],
    "InstallPackage"        => ["InstallPackage", "show"],
    "ViewInstallPackage"    => ["InstallPackage", "view"],
    "DoInstallPackage"      => ["InstallPackage", "do"],
    "ModifyReview"          => ["ModifyReview", "show"],
    "DoModifyReview"        => ["ModifyReview", "do"],
    "DoRemoveReviews"       => ["RemoveReviews", "do"],
    "Update"                => ["Update", "show"],
    "ViewUpdate"            => ["Update", "view"],
    "DoUpdate"              => ["Update", "do"],
    "Email"                 => ["Email", "show"],
    "DoEmail"               => ["Email", "do"],
    "CreateExtraField"      => ["CreateExtraField", "show"],
    "DoCreateExtraField"    => ["CreateExtraField", "do"],
    "ModifyExtraField"      => ["ModifyExtraField", "show"],
    "DoModifyExtraField"    => ["ModifyExtraField", "do"],
    "DoRemoveExtraFields"   => ["RemoveExtraFields", "do"],

    "ConvertDatabase"       => ["ConvertDatabase", "show"],
    "ViewConvertDatabase"   => ["ConvertDatabase", "view"],
    "DoConvertDatabase"     => ["ConvertDatabase", "do"]
  }
);

###############################################################################
# Main subroutine
sub Main {

  $| = 1;

  require "Error.pm.pl";
  require "Standard.pm.pl";
  use CGI;

  require "Database.$SYSTEM->{'DB_TYPE'}.pm.pl";
  my $DB = new Database;

  $SL::CGI = CGI->new();

  &Standard::ParseForm();
  &Standard::ParseCookies();
  &Standard::SetSkin(DB => $DB);
  &Standard::ProcessPlugins();

  if ($SYSTEM->{'INSTALLED'} == 0 && $SL::QUERY{'action'} ne "Install") {
    &Error::CGIError("SuperLinks has not been installed yet. Please run install.cgi before continuing.", "");
  } elsif ((-e "$SL::PATH/install.cgi" || -e "$SL::PATH/Private.tar") && ($SL::QUERY{'action'} ne "Install")) {
    &Error::CGIError("Please delete the install.cgi/pl and Private.tar files in the installation directory to avoid hacking.", "");
  }

  if ($SL::QUERY{'CP'}) {
    &ControlPanel(DB => $DB) and return 1;
  } else {
    &SuperLinks(DB => $DB) and return 1;
  }
}

###############################################################################
# SuperLinks subroutine
sub SuperLinks {
  my %in = (DB => undef, @_);

  my $Action = $SL::QUERY{'action'} || "Index";
  my $Page   = $SL::ACTIONS{'SL'}->{$Action};
  
  if (ref($Page) eq "CODE") {
    eval {
      &{ $Page }(DB => $in{'DB'});
    };
    if ($@) {
      &Error::CGIError("Error evaluating code reference. $@", "");
    } else {
      return 1;
    }
  } elsif ($Page) {
    require "$Page->[0].pm.pl";
    my $Source = eval($Page->[0]."->new()");
    eval("\$Source->".$Page->[1]."(DB => \$in{'DB'})");
    if ($@) {
      &Error::CGIError("Error evaluating the \"$Page->[1]\" subroutine in the \"$Page->[0]\" package. $@", "");
    } else {
      return 1;
    }
  } else {
    &Error::CGIError("Could not find action \"$Action\"", "");
  }
}

###############################################################################
# ControlPanel subroutine
sub ControlPanel {
  my %in = (DB => undef, @_);

  my $Action = $SL::QUERY{'action'} || "Index";
  my $Page   = $SL::ACTIONS{'CP'}->{$Action};

  if (ref($Page) eq "CODE") {
    eval &$Page;
    if ($@) {
      &Error::CGIError("Error evaluating code reference. $@", "");
    } else {
      return 1;
    }
  } elsif ($Page) {
    require "ControlPanel/$Page->[0].pm.pl";
    my $Source = eval("CP::".$Page->[0]."->new()");
    eval("\$Source->".$Page->[1]."(DB => \$in{'DB'})");
    if ($@) {
      &Error::CGIError("Error evaluating the \"$Page->[1]\" subroutine in the \"CP::$Page->[0]\" package. $@", "");
    } else {
      return 1;
    }
  } else {
    &Error::CGIError("Could not find action \"$Action\"", "");
  }
}

1;